package cn.isjinhao.se.util;

import cn.isjinhao.se.script.ScriptException;

/**
 * @Author ISJINHAO
 * @Date 2021/7/1 10:06
 */
public class CamelUnderlineUtil {

    private static final char UNDERLINE = '_';

    public static String camelToUnderline(String propertyName) {
        if (propertyName == null) {
            throw new ScriptException("待转为下划线格式的属性名称不能为空！");
        }
        propertyName = propertyName.trim();
        int len = propertyName.length();
        if (len == 0) {
            throw new ScriptException("待转为下划线格式的属性名称需要为有效名称！");
        }

        StringBuilder sb = new StringBuilder(len);
        boolean flag = false;
        for (int i = 0; i < len; i++) {
            char c = propertyName.charAt(i);
            if (Character.isUpperCase(c)) {
                flag = true;
                sb.append('_');
                sb.append(Character.toLowerCase(c));
            } else {
                sb.append(c);
                if (flag) {
                    flag = false;
                }
            }
        }
        return sb.toString();
    }


    /**
     * 下划线形式的字段转为驼峰形式
     * AIRPORT_CODE    ->  airportCode
     * AIRPORT__CODE   ->  airportCode
     * AIRPORT_4CODE   ->  airport4Code
     * AIRPORT__4CODE  ->  airport4Code
     * airport4_code4_airport_code  ->  airport4Code4AirportCode
     */
    public static String underlineToCamel(String camel) {
        if (camel == null) {
            throw new ScriptException("待转为驼峰格式的字段名称不能为空！");
        }

        camel = camel.trim();
        int len = camel.length();
        if (len == 0) {
            throw new ScriptException("待转为驼峰格式的字段名称需要为有效名称！");
        }

        StringBuilder sb = new StringBuilder(len);
        boolean flag = false;
        for (int i = 0; i < len; i++) {
            char c = camel.charAt(i);
            // 如果是两个__连在一起，会认为是一个_
            if (c == UNDERLINE) {
                flag = true;
            } else {
                // 如果_后面跟的是数字，则延迟到下一个字符再消除flag
                if (Character.isDigit(c)) {
                    sb.append(c);
                } else {
                    if (flag) {
                        sb.append(Character.toUpperCase(c));
                        flag = false;
                    } else {
                        sb.append(Character.toLowerCase(c));
                    }
                }
            }
        }
        return sb.toString();
    }

}
